package com.hm.shopping.service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Service;

import com.hm.common.def.DataStatusDef;
import com.hm.common.exception.ErrorCode;
import com.hm.common.exception.ServiceException;
import com.hm.common.su.bean.PageInfo;
import com.hm.common.su.bean.PageInfo.PageInfoParam;
import com.hm.common.util.ChineseToPinYinUtil;
import com.hm.common.util.CommonUtil;
import com.hm.common.util.Optional;
import com.hm.common.util.StringUtil;
import com.hm.core.SdkConfig;
import com.hm.shopping.auto.su.BaseDomain;
import com.hm.shopping.def.GoodsShelfStatusEnums;
import com.hm.shopping.domain.GoodsIntroductionDomain;
import com.hm.shopping.domain.QClassificationDetailDomain;
import com.hm.shopping.domain.QGoodsIntroductionDomain;
import com.hm.shopping.repository.ClassificationDetailRepository;
import com.hm.shopping.repository.GoodsIntroductionRepository;
import com.hm.shopping.su.BeanUtil;
import com.hm.shopping.vo.GoodsIntroductionVo;
import com.querydsl.core.types.dsl.BooleanExpression;

/**
 * @author shishun.wang
 * @date 2018年1月19日 下午5:03:28
 * @version 1.0
 * @describe
 */
@Service
public class GoodsIntroductionServiceImpl implements GoodsIntroductionService {

	@Autowired
	private GoodsIntroductionRepository goodsIntroductionRepository;

	@Autowired
	private ClassificationDetailRepository classificationDetailRepository;

	@Override
	public void addGoodsIntroduction(GoodsIntroductionVo goodsIntroductionVo) {
		if (CommonUtil.isAnyEmpty(goodsIntroductionVo.getShopsId(), goodsIntroductionVo.getClassificationCodes(), goodsIntroductionVo.getContentDetails(), goodsIntroductionVo.getGoodsIntroductionPics(), goodsIntroductionVo.getGoodsName(), goodsIntroductionVo.getBanner(),
				goodsIntroductionVo.getRemainingInventory(), goodsIntroductionVo.getUnitPrice(), goodsIntroductionVo.getGoodsAttributes(), goodsIntroductionVo.getGoodsParameters())) {
			throw ServiceException.warning(ErrorCode.PARAMETERS_MISSING);
		}

		goodsIntroductionVo.getClassificationCodes().forEach(code -> {
			if (!classificationDetailRepository.exists(QClassificationDetailDomain.classificationDetailDomain.classificationDetailCode.eq(code))) {
				throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND, "商品分类");
			}
		});

		GoodsIntroductionDomain domain = new GoodsIntroductionDomain();
		BeanUtil.copyProperties(goodsIntroductionVo, domain);
		BaseDomain.initBaseInfo(domain);
		domain.setGoodsAttributes(domain.getGoodsAttributes().parallelStream().map(item -> {
			item.setAttributeCode(ChineseToPinYinUtil.getPingYin(item.getAttributeType().replace("/", "_or_")).toUpperCase());
			AtomicBoolean defaultSelected = new AtomicBoolean(true);
			item.setAttributes(item.getAttributes().parallelStream().map(deatilVo -> {
				deatilVo.setCode(ChineseToPinYinUtil.getPingYin(deatilVo.getName().replace("/", "_or_")).toUpperCase());
				deatilVo.setDefaultSelected(defaultSelected.get());
				defaultSelected.set(false);
				return deatilVo;
			}).collect(Collectors.toList()));
			return item;
		}).collect(Collectors.toList()));
		domain.setRemainingInventory(domain.getInventory());
		domain.setUnitPrice(domain.getUnitPrice() * 100);// 元转分
		domain.setPromotionUnitPrice(domain.getPromotionUnitPrice() * 100);// 元转分
		goodsIntroductionRepository.save(domain);
	}

	@Override
	public GoodsIntroductionVo getGoodsIntroduction(String goodsId) {
		if (CommonUtil.isEmpty(goodsId)) {
			throw ServiceException.warning(ErrorCode.PARAMETERS_MISSING);
		}

		GoodsIntroductionDomain goodsIntroductionDomain = goodsIntroductionRepository.findOne(goodsId);
		if (CommonUtil.isEmpty(goodsIntroductionDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		GoodsIntroductionVo vo = new GoodsIntroductionVo();
		BeanUtil.copyProperties(goodsIntroductionDomain, vo);
		return vo;

	}

	@Override
	public List<GoodsIntroductionVo> getGoodsIntroductionsByShopsId(String shopsId) {

		return Optional.of(goodsIntroductionRepository.findAll(QGoodsIntroductionDomain.goodsIntroductionDomain.shopsId.eq(shopsId))).map(items -> {
			List<GoodsIntroductionVo> vos = new ArrayList<GoodsIntroductionVo>();
			items.forEach(item -> {
				GoodsIntroductionVo vo = new GoodsIntroductionVo();
				BeanUtil.copyProperties(item, vo);
				vos.add(vo);
			});

			return vos;
		}).get();
	}

	@Override
	public PageInfo<GoodsIntroductionVo> paggingGoodsIntroductions(String goodsName, String classificationDetailCode, PageInfoParam pageInfoParam) {
		QGoodsIntroductionDomain qGoodsIntroductionDomain = QGoodsIntroductionDomain.goodsIntroductionDomain;
		Pageable pageable = new QPageRequest(pageInfoParam.getPage(), pageInfoParam.getSize(), qGoodsIntroductionDomain.createTime.desc());

		BooleanExpression predicate = qGoodsIntroductionDomain.status.eq(DataStatusDef.ENABLE).and(qGoodsIntroductionDomain.goodsShelfStatus.eq(GoodsShelfStatusEnums.ONLINE));
		if (!StringUtil.isBlankOrNull(classificationDetailCode)) {
			predicate = predicate.and(qGoodsIntroductionDomain.classificationCodes.contains(classificationDetailCode));
		}

		if (!StringUtil.isBlankOrNull(goodsName)) {
			predicate = predicate.and(qGoodsIntroductionDomain.goodsName.like(goodsName));
		}
		Page<GoodsIntroductionDomain> page = goodsIntroductionRepository.findAll(predicate, pageable);

		return new PageInfo<GoodsIntroductionVo>(page.getContent().parallelStream().map(item -> {
			GoodsIntroductionVo vo = new GoodsIntroductionVo();
			BeanUtil.copyProperties(item, vo);
			return vo;
		}).collect(Collectors.toList()), page.getTotalPages(), page.getTotalElements());
	}

	@Override
	public List<GoodsIntroductionVo> goodsClassicalCollocationList(String goodsName, String classificationDetailCode) {
		QGoodsIntroductionDomain qGoodsIntroductionDomain = QGoodsIntroductionDomain.goodsIntroductionDomain;
		Pageable pageable = new QPageRequest(0, 10, qGoodsIntroductionDomain.salesAmount.desc());// 按销量推荐

		BooleanExpression predicate = qGoodsIntroductionDomain.status.eq(DataStatusDef.ENABLE).and(qGoodsIntroductionDomain.goodsShelfStatus.eq(GoodsShelfStatusEnums.ONLINE));
		if (!StringUtil.isBlankOrNull(classificationDetailCode)) {
			predicate = predicate.and(qGoodsIntroductionDomain.classificationCodes.contains(classificationDetailCode));
		}

		if (!StringUtil.isBlankOrNull(goodsName)) {
			predicate = predicate.and(qGoodsIntroductionDomain.goodsName.like(goodsName));
		}

		return Optional.of(goodsIntroductionRepository.findAll(predicate, pageable).getContent()).map(items -> {
			return items.parallelStream().map(item -> {
				GoodsIntroductionVo vo = new GoodsIntroductionVo();
				BeanUtil.copyProperties(item, vo);
				return vo;
			}).collect(Collectors.toList());
		}).get();
	}

	@Override
	public void updateGoodsIntroduction(GoodsIntroductionVo goodsIntroductionVo) {
		if (CommonUtil.isAnyEmpty(goodsIntroductionVo.getId(), goodsIntroductionVo.getShopsId(), goodsIntroductionVo.getClassificationCodes(), goodsIntroductionVo.getContentDetails(), goodsIntroductionVo.getGoodsIntroductionPics(), goodsIntroductionVo.getGoodsName(), goodsIntroductionVo.getBanner(),
				goodsIntroductionVo.getRemainingInventory(), goodsIntroductionVo.getUnitPrice(), goodsIntroductionVo.getGoodsAttributes(), goodsIntroductionVo.getGoodsParameters())) {
			throw ServiceException.warning(ErrorCode.PARAMETERS_MISSING);
		}

		GoodsIntroductionDomain goodsIntroductionDomain = goodsIntroductionRepository.findOne(goodsIntroductionVo.getId());
		if (CommonUtil.isEmpty(goodsIntroductionDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		goodsIntroductionVo.getClassificationCodes().forEach(classificationDetailId -> {
			if (!classificationDetailRepository.exists(QClassificationDetailDomain.classificationDetailDomain.id.eq(classificationDetailId))) {
				throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND, "商品分类");
			}
		});

		goodsIntroductionDomain.setClassificationCodes(goodsIntroductionVo.getClassificationCodes());
		goodsIntroductionDomain.setContentDetails(goodsIntroductionVo.getContentDetails());
		goodsIntroductionDomain.setGoodsIntroductionPics(goodsIntroductionVo.getGoodsIntroductionPics());
		goodsIntroductionDomain.setGoodsName(goodsIntroductionVo.getGoodsName());
		goodsIntroductionDomain.setBanner(goodsIntroductionVo.getBanner());
		goodsIntroductionDomain.setRemainingInventory(goodsIntroductionVo.getRemainingInventory());
		goodsIntroductionDomain.setUnitPrice(goodsIntroductionVo.getUnitPrice());
		goodsIntroductionDomain.setGoodsAttributes(goodsIntroductionVo.getGoodsAttributes().parallelStream().map(item -> {
			item.setAttributeCode(ChineseToPinYinUtil.getPingYin(item.getAttributeType().replace("/", "_or_")).toUpperCase());
			item.setAttributes(item.getAttributes().parallelStream().map(deatilVo -> {
				deatilVo.setCode(ChineseToPinYinUtil.getPingYin(deatilVo.getName().replace("/", "_or_")).toUpperCase());
				return deatilVo;
			}).collect(Collectors.toList()));
			return item;
		}).collect(Collectors.toList()));
		goodsIntroductionDomain.setUnitPrice(goodsIntroductionDomain.getUnitPrice() * 100);// 元转分
		goodsIntroductionDomain.setPromotionUnitPrice(goodsIntroductionDomain.getPromotionUnitPrice() * 100);// 元转分
		goodsIntroductionDomain.setGoodsParameters(goodsIntroductionVo.getGoodsParameters());

		goodsIntroductionRepository.save(goodsIntroductionDomain);
	}

	@Override
	public void deleteGoodsIntroduction(String goodsId) {
		if (CommonUtil.isEmpty(goodsId)) {
			throw ServiceException.warning(ErrorCode.PARAMETERS_MISSING);
		}

		GoodsIntroductionDomain goodsIntroductionDomain = goodsIntroductionRepository.findOne(goodsId);
		if (CommonUtil.isEmpty(goodsIntroductionDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		goodsIntroductionDomain.setStatus(DataStatusDef.DISABLE);
		goodsIntroductionRepository.save(goodsIntroductionDomain);
	}

	@Override
	public void updateGoodsIntroductionStatus(String goodsId, GoodsShelfStatusEnums goodsShelfStatus) {
		if (CommonUtil.isAnyEmpty(goodsId, goodsShelfStatus)) {
			throw ServiceException.warning(ErrorCode.PARAMETERS_MISSING);
		}

		GoodsIntroductionDomain goodsIntroductionDomain = goodsIntroductionRepository.findOne(goodsId);
		if (CommonUtil.isEmpty(goodsIntroductionDomain)) {
			throw ServiceException.warning(ErrorCode.DATA_NOT_FOUND);
		}

		goodsIntroductionDomain.setGoodsShelfStatus(goodsShelfStatus);
		goodsIntroductionRepository.save(goodsIntroductionDomain);
	}

	@Override
	public PageInfo<GoodsIntroductionVo> queryGoodsIntroduction(PageInfoParam pageParam, String shopsId, String goodsName) {
		QGoodsIntroductionDomain qGoodsIntroductionDomain = QGoodsIntroductionDomain.goodsIntroductionDomain;
		Pageable pageable = new QPageRequest(pageParam.getPage(), pageParam.getSize(), qGoodsIntroductionDomain.createTime.desc());

		BooleanExpression predicate = qGoodsIntroductionDomain.status.eq(DataStatusDef.ENABLE);
		if (Long.parseLong(shopsId) != SdkConfig.SUPER_ADMIN) {
			predicate = predicate.and(qGoodsIntroductionDomain.shopsId.eq(shopsId));
		}

		if (StringUtil.isNotBlank(goodsName)) {
			predicate = predicate.and(qGoodsIntroductionDomain.goodsName.like(goodsName));
		}

		Page<GoodsIntroductionDomain> page = goodsIntroductionRepository.findAll(predicate, pageable);

		return new PageInfo<GoodsIntroductionVo>(page.getContent().parallelStream().map(item -> {
			GoodsIntroductionVo vo = new GoodsIntroductionVo();
			BeanUtil.copyProperties(item, vo);
			vo.setCreateTime(item.getCreateTime().getTime());

			return vo;
		}).collect(Collectors.toList()), page.getTotalPages(), page.getTotalElements());
	}

	@Override
	public List<GoodsIntroductionVo> guessLikeGoodsList(List<String> classificationDetailCode) {
		List<GoodsIntroductionVo> vos = new ArrayList<GoodsIntroductionVo>();
		goodsIntroductionRepository.findAll(QGoodsIntroductionDomain.goodsIntroductionDomain.classificationCodes.contains(classificationDetailCode.get(0))).forEach(item -> {
			GoodsIntroductionVo vo = new GoodsIntroductionVo();
			BeanUtil.copyProperties(item, vo);

			vos.add(vo);
		});
		return vos;
	}
}
